package cn.school.student.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.school.classManage.service.SchoolClassService;
import cn.school.classManage.vo.SchoolClassVO;
import cn.school.common.utils.SysUserUtils;
import cn.school.student.dao.ExamInfoDao;
import cn.school.student.dao.ExamResultInfoDao;
import cn.school.student.dao.StudentExamInfoDao;
import cn.school.student.dao.StudentInfoDao;
import cn.school.student.entity.ExamInfoChartLine;
import cn.school.student.entity.StudentExamInfo;
import cn.school.student.entity.StudentInfo;
import cn.school.student.service.ExamInfoService;
import cn.school.student.vo.ExamInfoVO;
import cn.school.student.vo.ExamResultInfoVO;
import cn.school.sys.dao.TermTimeDao;
import cn.school.sys.entity.SysDictDetail;
import cn.school.sys.entity.SysUser;
import cn.school.sys.entity.SysUserRole;
import cn.school.sys.entity.TermTime;
import cn.school.sys.service.SysDictDetailService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExamInfoServiceImpl extends ServiceImpl<ExamInfoDao, ExamInfoVO> implements ExamInfoService {

    @Resource
    private ExamInfoDao examInfoDao;
    
    @Resource
    private StudentExamInfoDao studentExamInfoDao;
    
    @Resource
    private ExamResultInfoDao examResultInfoDao;

    @Override
    public IPage<ExamInfoVO> findExamInfoPageList(ExamInfoVO vo) {
        String username = SysUserUtils.getSysUser().getUsername();
        List<SysUserRole> roleInfoList = SysUserUtils.getSysUser().getRoleInfoList();
        List<String> roleNames = roleInfoList.stream().map(SysUserRole::getRoleName).collect(Collectors.toList());
        if (roleNames.contains("超级管理员")) {
            username = "";
        }
        vo.setClassTeacherId(username);
        
        int count =  examInfoDao.findExamInfoPageListCount(vo);
        int startNum=(vo.getPageNum()-1)*vo.getPageSize();
        vo.setPageNum(startNum);
        List<ExamInfoVO> examInfoList =  examInfoDao.findExamInfoPageList(vo);
        if (CollectionUtil.isNotEmpty(examInfoList)) {
            // 查看成绩结果表看是否有录入
            List<Long> examIds = examInfoList.stream().map(ExamInfoVO::getId).collect(Collectors.toList());
            LambdaQueryWrapper<ExamResultInfoVO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(ExamResultInfoVO::getExamId, examIds);
            List<ExamResultInfoVO> resultInfoVOS = examResultInfoDao.selectList(queryWrapper);
    
            Map<String, List<ExamResultInfoVO>> collect = resultInfoVOS.stream().collect(Collectors.groupingBy(ExamResultInfoVO::getExamId));
            for (ExamInfoVO examInfoVO : examInfoList) {
                if (CollectionUtil.isNotEmpty(collect.get(String.valueOf(examInfoVO.getId())))) {
                    examInfoVO.setIsGradeEnter(true);
                    continue;
                }
                examInfoVO.setIsGradeEnter(false);
            }
        }
    
        IPage<ExamInfoVO> page = new Page<>();
        page.setTotal(count);
        page.setRecords(examInfoList);
        return page;
    }

    @Override
    public int addOrUpdateExamInfo(ExamInfoVO vo) {
        String userName = SysUserUtils.getSysUser().getUsername();
        int num = 0;
        if(StringUtils.isEmpty(vo.getId())){
            vo.setCreateBy(userName);
            vo.setCreateTime(new Date());
            num = this.baseMapper.insert(vo);
        }else{
            vo.setModifyBy(userName);
            vo.setModifyTime(new Date());
            num = this.baseMapper.updateById(vo);
        }
        return num;
    }

    @Override
    public int deleteExamInfoById(String id) {
        return this.baseMapper.deleteById(id);
    }

    @Override
    public int deleteBatchExamInfo(List<ExamInfoVO> list) {
        int num = 0;
        for (ExamInfoVO vo: list){
            this.baseMapper.deleteById(vo.getId());
            num ++ ;
        }
        return num;
    }

    @Override
    public int updateBatchExamInfo(List<ExamInfoVO> list) {
        int num = 0;
        for (ExamInfoVO vo: list){
            this.baseMapper.updateById(vo);
            num ++ ;
        }
        return num;
    }
    
    @Override
    public List<StudentExamInfo> getGradesByStudentId(String studentId) {
        LambdaQueryWrapper<StudentExamInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentExamInfo::getStudentId, String.valueOf(studentId));
        return studentExamInfoDao.selectList(queryWrapper);
    }
    
    @Override
    public List<ExamInfoChartLine> getGradesLineChart(String studentId) {
        LambdaQueryWrapper<StudentExamInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentExamInfo::getStudentId, String.valueOf(studentId));
        List<StudentExamInfo> examInfos = studentExamInfoDao.selectList(queryWrapper);
        // 学科名称
        Set<String> collect = examInfos.stream().map(StudentExamInfo::getExamCourse).collect(Collectors.toSet());
    
        List<ExamInfoChartLine> resultList = new ArrayList<>();
        for (String courseName : collect) {
            ExamInfoChartLine chartLine = new ExamInfoChartLine();
            chartLine.setSubjectName(courseName);
            List<StudentExamInfo> infos = examInfos.stream().filter(studentExamInfo -> Objects.equals(studentExamInfo.getExamCourse(), courseName)).collect(Collectors.toList());
            
            if (CollectionUtil.isEmpty(infos)) {
                continue;
            }
            List<Map<String, String>> examInfoList = new ArrayList<>();
            for (StudentExamInfo info : infos) {
                Map<String, String> map = new HashMap<>();
                map.put("time", info.getExamBeginTime());
                map.put("examName", info.getExamName());
                map.put("score", info.getScore());
                map.put("term", info.getTerm());
                examInfoList.add(map);
            }
            chartLine.setDataList(examInfoList);
            resultList.add(chartLine);
        }
        
        return resultList;
    }

    @Resource
    SchoolClassService schoolClassService;
    @Resource
    SysDictDetailService sysDictDetailService;
    @Resource
    TermTimeDao termTimeDao;
    @Autowired
    StudentInfoDao studentInfoDao;
    @Override
    public String importExcel(InputStream inputStream, ExamInfoVO vo) throws IOException {

        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
        //读取第一个sheet
        XSSFSheet sheet = workbook.getSheetAt(0);
        //保存学生姓名
        List<String> studentNameList = new ArrayList<>();
        //保存科目名称
        List<String> subjList = new ArrayList<>();
        //班级ID
        String classId = "";
        //考试内容
        ExamInfoVO infoVO = new ExamInfoVO();
        infoVO.setExamBeginTime(vo.getExamBeginTime());
        infoVO.setExamEndTime(vo.getExamEndTime());
        //考试结果内容
        ExamResultInfoVO resultInfoVO = new ExamResultInfoVO();
        //保存分数标题
        List<String> sourceList = new ArrayList<>();
        List<List<String>> allDataList = new ArrayList<>();

        // 获取行
        for (int i=0; i<sheet.getPhysicalNumberOfRows();i++) {
            //获取每行的内容
            Row row = sheet.getRow(i);
            if(i==0){
                //考试名称
                Cell cell = row.getCell(1);
                infoVO.setExamName(cell.getStringCellValue());
            }
            if(i==1){
                //第二行 班级名称
                Cell cell = row.getCell(1);
                String className = cell.getStringCellValue();
                SchoolClassVO existsClassVO = classExists(className);
                if(existsClassVO!=null){
                    infoVO.setClassId(String.valueOf(existsClassVO.getId()));
                    infoVO.setClassName(existsClassVO.getClassName());
                }else{
                    return "班级名称不存在，请检查后再提交";
                }

            }
            if(i==2){
                //第二行取科目名称
                for (int j=1; j<row.getLastCellNum();j++){
                    Cell cell = row.getCell(j);
                    String subjName = cell.getStringCellValue();
                    //查询班级名称是否正确
                    subjList.add(subjName);
                }


            }
            if(i==3){
                //第三行取分数和是否通过标题
                for (int j=0; j<row.getLastCellNum();j++){
                    Cell cell = row.getCell(j);
                    sourceList.add(cell.getStringCellValue());
                }
            }
            if(i>3){
                //保存数据
                List<String> dataList = new ArrayList<>();
                //取文件数据按下标获取
                for (int j=0; j<row.getLastCellNum();j++){
                    Cell cell = row.getCell(j);
                    CellType cellType = cell.getCellTypeEnum();
                    String value="";
                    switch (cellType) {
                        case NUMERIC://数字
                            value = cell.getNumericCellValue()+"";
                            break;
                        case STRING://字符
                            value = cell.getStringCellValue();
                            break;
                    }
                    if(j==0){
                        //学生姓名
                        studentNameList.add(value);
                    }else{
                        //考试分数
                        dataList.add(value);
                    }
                }
                allDataList.add(dataList);
            }

        }

        //去掉重复的科目
        System.out.println(subjList);
        subjList = subjList.stream().distinct().collect(Collectors.toList());
        System.out.println(subjList);
        //查询科目名称是否存在
        List<SysDictDetail> courseTypeList = sysDictDetailService.selectDictDataByType("course_type");
        if(courseTypeList.size()!=subjList.size()){
            return "考试课程有误，请检查后重新提交";
        }
        //获取考试时间所在的学期ID
        LambdaQueryWrapper<TermTime> termWrapper = new LambdaQueryWrapper<>();
        termWrapper.ge(TermTime::getTetiTermEndDate,vo.getExamBeginTime());
        termWrapper.le(TermTime::getTetiTermBeginDate,vo.getExamBeginTime());
        List<TermTime> termTimes = termTimeDao.selectList(termWrapper);
        if(termTimes==null || termTimes.size()==0){
            return "不能匹配到考试时间所在的学期";
        }
        LambdaQueryWrapper<StudentInfo> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.in(StudentInfo::getName, studentNameList);
        studentWrapper.eq(StudentInfo::getTenantId,SysUserUtils.getSysUser().getTenantId());
        studentWrapper.eq(StudentInfo::getClassId,infoVO.getClassId());
        List<StudentInfo> studentInfos = studentInfoDao.selectList(studentWrapper);
        for (String s : studentNameList) {
            int num = 0;
            for (StudentInfo studentInfo : studentInfos) {
                if(!s.equals(studentInfo.getName())){
                    num++;
                }
            }
            if(num==studentInfos.size()){
                return "学生："+s+"不在系统中，请检查后重新上传";
            }
        }
        if(studentInfos.size() != studentNameList.size()){
            return "不能匹配到考试时间所在的学期";
        }

        //添加考试信息
        saveExamInfo(infoVO, courseTypeList, termTimes,studentInfos,allDataList,studentNameList);
        System.out.println(sourceList);
        System.out.println(allDataList);
        return null;
    }

    private String getValue(List<SysDictDetail> courseTypeList,String lable){
        for (SysDictDetail sysDictDetail : courseTypeList) {
            if(sysDictDetail.getDictLabel().equals(lable)){
                return sysDictDetail.getDictValue();
            }
        }
        return null;
    }

    private String getStudentId(String name,List<StudentInfo> studentInfos){
        for (StudentInfo studentInfo : studentInfos) {
            if(name.equals(studentInfo.getName())){
                return studentInfo.getStudentId();
            }
        }
        return null;
    }

    private void saveExamInfo(ExamInfoVO infoVO, List<SysDictDetail> courseTypeList, List<TermTime> termTimes,
                              List<StudentInfo> studentInfos,List<List<String>> allDataList,List<String> studentNameList) {

        List<ExamResultInfoVO> resultVOList = null;
        int num = 0;
        for (int i=0;i<courseTypeList.size();i++) {
            resultVOList = new ArrayList<>();
            SysDictDetail sysDictDetail = courseTypeList.get(i);
            ExamInfoVO examInfoVO = new ExamInfoVO();
            examInfoVO.setClassName(infoVO.getClassName());
            examInfoVO.setClassId(infoVO.getClassId());
            examInfoVO.setExamName(infoVO.getExamName()+"-"+sysDictDetail.getDictLabel());
            examInfoVO.setTermId(String.valueOf(termTimes.get(0).getId()));
            examInfoVO.setCurriculumType(sysDictDetail.getDictValue());
            examInfoVO.setExamBeginTime(infoVO.getExamBeginTime());
            examInfoVO.setExamEndTime(infoVO.getExamEndTime());
            examInfoVO.setCreateTime(new Date());
            examInfoVO.setCreateBy(SysUserUtils.getSysUser().getUsername());
            this.baseMapper.insert(examInfoVO);
            //添加学生成绩 TODO

            ExamResultInfoVO examResultInfoVO = null;

            int passNum = (num +1);
            for (int i1 = 0; i1 < studentNameList.size(); i1++) {
                examResultInfoVO = new ExamResultInfoVO();
                examResultInfoVO.setExamId(String.valueOf(examInfoVO.getId()));
                examResultInfoVO.setStudentName(studentNameList.get(i1));
                examResultInfoVO.setStudentCode(getStudentId(studentNameList.get(i1),studentInfos));
                examResultInfoVO.setStudentClassId(infoVO.getClassId());
                examResultInfoVO.setStudentClassName(infoVO.getClassName());
                List<String> strings = allDataList.get(i1);
                examResultInfoVO.setScore(strings.get(num));
                examResultInfoVO.setIsPass(strings.get(passNum).equals("是")?"1":"0");


                resultVOList.add(examResultInfoVO);
            }
            num = (passNum+1);

            if(resultVOList.size()>0){
                for (ExamResultInfoVO resultInfoVO : resultVOList) {
                    resultInfoVO.setCreateTime(new Date());
                    resultInfoVO.setCreateBy(SysUserUtils.getSysUser().getUsername());
                    examResultInfoDao.insert(resultInfoVO);
                }

            }

            
        }
    }

    private SchoolClassVO classExists(String className) {
        SchoolClassVO classvo = new SchoolClassVO();
        classvo.setClassName(className);
        List<SchoolClassVO> resultClassVOList = schoolClassService.findClassInfo(classvo);
        if(resultClassVOList==null || resultClassVOList.size()==0 || resultClassVOList.size()>1){
            return null;
        }
        return resultClassVOList.get(0);
    }

    public static void main(String[] args) {
        int num =0;
        int pass = num+1;
        System.out.println(num);


    }
}
